package test.marui.com.mytest.view.verifyEditView.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.support.annotation.Nullable;
import android.text.Editable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import test.marui.com.mytest.R;
import test.marui.com.mytest.utils.DisplayUtil;


/**
 * Created by MR on 2019/1/4.
 */
public class VerifyEditText extends LinearLayout {

    private Context mContext;

    private int inputCount;
    private int inputSpace;
    private int underLineHeight;
    private int mTextSize;
    private int lineFocusColor;
    private int lineDefaultColor;
    private int underlineSpace;
    private int cursorDrawable;

    private List<HelpEditText> mEditTextList;
    private List<View> mUnderlineList;

    private final int DEFAULT_INPUT_COUNT;
    private final int DEFAULT_INPUT_SPACE;
    private final int DEFAULT_UNDERLINE_HEIGHT;
    private final int DEFAULT_TEXT_SIZE;
    private final int DEFAULT_FOCUS_COLOR;
    private final int DEFAULT_DEFAULT_COLOR;
    private final int DEFAULT_UNDERLINE_SPACE;
    private final int DEFAULT_CURSOR_DRAWABLE;

    private int currentPosition;
    private boolean isAllLineLight;

    private VerifyEditText.InputCompleteListener mInputCompleteListener;

    public VerifyEditText(Context context) {
        this(context, null);
    }

    public VerifyEditText(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public VerifyEditText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        this.mContext = context;
        this.DEFAULT_INPUT_COUNT = 4;
        this.DEFAULT_INPUT_SPACE = DisplayUtil.dip2px(this.mContext, 4);
        this.DEFAULT_UNDERLINE_HEIGHT = DisplayUtil.dip2px(this.mContext, 1);
        this.DEFAULT_TEXT_SIZE = DisplayUtil.dip2px(this.mContext, 8);
        this.DEFAULT_FOCUS_COLOR = Color.RED;
        this.DEFAULT_DEFAULT_COLOR = Color.BLACK;
        this.DEFAULT_UNDERLINE_SPACE = 0;
        this.DEFAULT_CURSOR_DRAWABLE = R.drawable.edit_cursor_shape;

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.VerifyEditText);

        if (typedArray != null) {
            inputCount = typedArray.getInteger(R.styleable.VerifyEditText_inputCount, this.DEFAULT_INPUT_COUNT);
            inputSpace = (int) typedArray.getDimension(R.styleable.VerifyEditText_inputSpace, this.DEFAULT_INPUT_SPACE);
            underLineHeight = (int) typedArray.getDimension(R.styleable.VerifyEditText_underLineHeight, this.DEFAULT_UNDERLINE_HEIGHT);
            mTextSize = (int) typedArray.getDimension(R.styleable.VerifyEditText_mTextSize, this.DEFAULT_TEXT_SIZE);
            lineFocusColor = typedArray.getColor(R.styleable.VerifyEditText_focusColor, this.DEFAULT_FOCUS_COLOR);
            lineDefaultColor = typedArray.getColor(R.styleable.VerifyEditText_defaultColor, this.DEFAULT_DEFAULT_COLOR);
            underlineSpace = (int) typedArray.getDimension(R.styleable.VerifyEditText_underlineSpace, this.DEFAULT_UNDERLINE_SPACE);
            cursorDrawable = typedArray.getResourceId(R.styleable.VerifyEditText_cursorDrawable, this.DEFAULT_CURSOR_DRAWABLE);
            typedArray.recycle();
        }

        this.initView();

    }

    private void initView() {
        if (this.inputCount > 0) {
            this.setOrientation(LinearLayout.HORIZONTAL);
            this.setGravity(Gravity.CENTER);
            this.mEditTextList = new ArrayList<>();
            this.mUnderlineList = new ArrayList<>();

            for (int i = 0; i < this.inputCount; i++) {

                LayoutParams flParams = new LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
                flParams.setMargins(i == 0 ? 0 : this.inputSpace, 0, 0, 0);
                FrameLayout frameLayout = new FrameLayout(this.mContext);
                frameLayout.setLayoutParams(flParams);

                android.widget.FrameLayout.LayoutParams etParams = new android.widget.FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
                HelpEditText et = new HelpEditText(this.mContext);
                et.setBackground(null);
                et.setPadding(0, 0, 0, this.underlineSpace);
                et.setMaxLines(1);
                et.setTextSize(this.mTextSize);

                InputFilter[] filters = {new InputFilter.LengthFilter(1)};
                et.setFilters(filters);
                et.setInputType(InputType.TYPE_CLASS_NUMBER);
                et.setGravity(Gravity.CENTER);

                try {
                    Field field = TextView.class.getDeclaredField("mCursorDrawableRes");
                    field.setAccessible(true);
                    field.set(et, this.cursorDrawable);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                et.setLayoutParams(etParams);
                frameLayout.addView(et);

                android.widget.FrameLayout.LayoutParams underlineParams = new android.widget.FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, this.underLineHeight);
                underlineParams.gravity = Gravity.BOTTOM;
                View underline = new View(this.mContext);
                underline.setBackgroundColor(this.lineDefaultColor);
                underline.setLayoutParams(underlineParams);
                frameLayout.addView(underline);
                this.addView(frameLayout);
                this.mEditTextList.add(et);
                this.mUnderlineList.add(underline);

            }

            OnFocusChangeListener mOnFocusChangeListener = new OnFocusChangeListener() {
                @Override
                public void onFocusChange(View v, boolean hasFocus) {
                    for (int i = 0; i < VerifyEditText.this.mEditTextList.size(); i++) {
                        if (VerifyEditText.this.mEditTextList.get(i).isFocused()) {
                            VerifyEditText.this.currentPosition = i;
                            Log.e("VerifyEditText",String.valueOf(VerifyEditText.this.currentPosition));
                        }

                        if (!isAllLineLight) {
                            VerifyEditText.this.mUnderlineList.get(i).setBackgroundColor(VerifyEditText.this.lineDefaultColor);
                        }
                    }

                    if (!isAllLineLight) {
                        VerifyEditText.this.mUnderlineList.get(VerifyEditText.this.currentPosition).setBackgroundColor(VerifyEditText.this.lineFocusColor);
                    }
                }
            };

            TextWatcher mTextWatcher = new TextWatcher() {

                private String getCompleteContent() {

                    if (VerifyEditText.this.mEditTextList == null) {
                        return "";
                    }

                    StringBuffer completeContent = new StringBuffer();
                    for (int i = 0; i < VerifyEditText.this.mEditTextList.size(); i++) {
                        completeContent.append(VerifyEditText.this.mEditTextList.get(i).getText().toString());
                    }
                    return completeContent.toString();
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {

                    if (!(s.toString().isEmpty()) && VerifyEditText.this.currentPosition < VerifyEditText.this.mEditTextList.size() - 1) {
                        VerifyEditText.this.currentPosition++;
                        VerifyEditText.this.mEditTextList.get(VerifyEditText.this.currentPosition).requestFocus();
                    }

                    if (VerifyEditText.this.isCompleteInput() && VerifyEditText.this.mInputCompleteListener != null) {
                        VerifyEditText.this.mInputCompleteListener.inputComplete(VerifyEditText.this, getCompleteContent());
                    }

                }
            };

            OnKeyListener mOnKeyListener = new OnKeyListener() {
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    if (keyCode == 67) {
                        if (event.getAction() != 0) {
                            return true;
                        }

                        if (VerifyEditText.this.mEditTextList.get(VerifyEditText.this.currentPosition).getText().toString().isEmpty()) {
                            if (VerifyEditText.this.currentPosition <= 0) {
                                return true;
                            }

                            for (int i = VerifyEditText.this.currentPosition; i >= 0; i--) {
                                VerifyEditText.this.currentPosition = i;
                                if (!(VerifyEditText.this.mEditTextList.get(i).getText().toString().isEmpty())) {
                                    break;
                                }
                            }
                        }

                        VerifyEditText.this.mEditTextList.get(VerifyEditText.this.currentPosition).requestFocus();
                        VerifyEditText.this.mEditTextList.get(VerifyEditText.this.currentPosition).getText().clear();

                        return true;
                    }
                    return false;
                }
            };

            Iterator<HelpEditText> iterator = this.mEditTextList.iterator();
            HelpEditText et;
            while (iterator.hasNext()) {
                et = iterator.next();
                et.setOnFocusChangeListener(mOnFocusChangeListener);
                et.addTextChangedListener(mTextWatcher);
                et.setOnKeyListener(mOnKeyListener);
            }

            this.mEditTextList.get(0).requestFocus();
        }
    }

    private boolean isCompleteInput() {

        if (VerifyEditText.this.mEditTextList == null)
            return false;

        Iterator<HelpEditText> iterator = VerifyEditText.this.mEditTextList.iterator();
        HelpEditText next;
        do {

            if (!iterator.hasNext())
                return true;

            next = iterator.next();
        } while (!(next.getText().toString().isEmpty()));

        return false;
    }


    public interface InputCompleteListener {
        void inputComplete(VerifyEditText view, String content);
    }

    public void setInputCompleteListener(InputCompleteListener mInputCompleteListener) {
        this.mInputCompleteListener = mInputCompleteListener;
    }

    public int getInputCount() {
        return inputCount;
    }

    public VerifyEditText setInputCount(int inputCount) {
        this.inputCount = inputCount;
        return this;
    }

    public int getInputSpace() {
        return inputSpace;
    }

    public VerifyEditText setInputSpace(int inputSpace) {
        this.inputSpace = inputSpace;
        return this;
    }

    public int getUnderLineHeight() {
        return underLineHeight;
    }

    public VerifyEditText setUnderLineHeight(int underLineHeight) {
        this.underLineHeight = underLineHeight;
        return this;
    }

    public int getmTextSize() {
        return mTextSize;
    }

    public VerifyEditText setmTextSize(int mTextSize) {
        this.mTextSize = mTextSize;
        return this;
    }

    public int getLineFocusColor() {
        return lineFocusColor;
    }

    public VerifyEditText setLineFocusColor(int lineFocusColor) {
        this.lineFocusColor = lineFocusColor;
        return this;
    }

    public int getLineDefaultColor() {
        return lineDefaultColor;
    }

    public VerifyEditText setLineDefaultColor(int lineDefaultColor) {
        this.lineDefaultColor = lineDefaultColor;
        return this;
    }

    public int getUnderlineSpace() {
        return underlineSpace;
    }

    public VerifyEditText setUnderlineSpace(int underlineSpace) {
        this.underlineSpace = underlineSpace;
        return this;
    }

    public int getCursorDrawable() {
        return cursorDrawable;
    }

    public VerifyEditText setCursorDrawable(int cursorDrawable) {
        this.cursorDrawable = cursorDrawable;
        return this;
    }


    public int getCurrentPosition() {
        return currentPosition;
    }

    public VerifyEditText setCurrentPosition(int currentPosition) {
        this.currentPosition = currentPosition;
        return this;
    }

    public boolean isAllLineLight() {
        return isAllLineLight;
    }

    public VerifyEditText setAllLineLight(boolean allLineLight) {
        isAllLineLight = allLineLight;
        return this;
    }
}
